#include "hc165_quad.h"
#include "stm32f4xx.h"
static inline void delay_1us(void)
{
    for (uint32_t i = 0; i < 42; i++)
        __NOP(); // 168 MHz 约 1 µs
}

/**
 * @brief  初始化74HC165所需的GPIO
 * @param  无
 * @retval 无
 */
void HC165_Init(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;

    // 使能相关GPIO时钟
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOG | RCC_AHB1Periph_GPIOD, ENABLE);

    // 配置PL和CLK为推挽输出
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
    GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;

    // 配置PL引脚 (PG9)
    GPIO_InitStructure.GPIO_Pin = HC165_PL_PIN;
    GPIO_Init(HC165_PL_PORT, &GPIO_InitStructure);

    // 配置CLK引脚 (PG12)
    GPIO_InitStructure.GPIO_Pin = HC165_CLK_PIN;
    GPIO_Init(HC165_CLK_PORT, &GPIO_InitStructure);

    // 配置DATA引脚为输入 (PD6)
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; // 上拉输入
    GPIO_InitStructure.GPIO_Pin = HC165_DATA_PIN;
    GPIO_Init(HC165_DATA_PORT, &GPIO_InitStructure);

    // 初始化状态
    HC165_PL_HIGH();
    HC165_CLK_HIGH();
}
/**
 * @brief  读取4片级联的74HC165数据(共32位)
 * @param  无
 * @retval 读取到的32位数据，高位先出
 */
uint32_t HC165_Read32Bits(void)
{
    uint32_t data = 0;
    uint8_t i;

    // 拉低PL，加载并行数据到寄存器
    HC165_PL_LOW();
    delay_1us(); // 短暂延时确保数据加载完成

    // 拉高PL，进入移位模式
    HC165_PL_HIGH();
    delay_1us();

    // 读取32位数据 (4片×8位)
    for (i = 0; i < 32; i++)
    {
        // 先将数据左移一位
        data <<= 1;

        // 读取当前位数据
        if (HC165_DATA_IN())
        {
            data |= 0x01; // 如果输入为高，设置最低位为1
        }

        // 时钟脉冲：先低后高
        HC165_CLK_LOW();
        delay_1us();
        HC165_CLK_HIGH();
        delay_1us();
    }

    return data;
}

